package com.md.common.utils;

import java.math.BigDecimal;

/**
 * 高精度Double数值操作<br/>
 * 直接double相加会出现精度不准确的问题<br/>
 * {@code System.out.println(0.05+0.01);} 会出现0.060000000000000005
 * 
 * @author Ice
 *
 */
public class DoubleUtils {

	private static final int DEF_DIVIDE_SCALE = 10;

	/**
	 * 相加两个double数值
	 * 
	 * @param augend
	 *            加数
	 * @param addend
	 *            加数
	 * @return
	 */
	public static double add(double augend, double addend) {
		BigDecimal b1 = new BigDecimal(Double.toString(augend));
		BigDecimal b2 = new BigDecimal(Double.toString(addend));
		return b1.add(b2).doubleValue();
	}

	public static double add(double augend, double... addends) {
		if (addends.length <= 0)
			return augend;
		BigDecimal b1 = new BigDecimal(Double.toString(augend));
		for (double addend : addends) {
			BigDecimal b2 = new BigDecimal(Double.toString(addend));
			b1 = b1.add(b2);
		}
		return b1.doubleValue();
	}
	
	/**
	 * 两个double数值相减
	 * 
	 * @param minuend
	 *            被减数
	 * @param subtrahend
	 *            减数
	 * @return
	 */
	public static double subtract(double minuend, double subtrahend) {
		BigDecimal b1 = new BigDecimal(Double.toString(minuend));
		BigDecimal b2 = new BigDecimal(Double.toString(subtrahend));
		return b1.subtract(b2).doubleValue();
	}

	/**
	 * 两个double数值相乘
	 * 
	 * @param multiplicand
	 *            乘数
	 * @param multiplier
	 *            乘数
	 * @return
	 */
	public static double multiply(double multiplicand, double multiplier) {
		BigDecimal b1 = new BigDecimal(Double.toString(multiplicand));
		BigDecimal b2 = new BigDecimal(Double.toString(multiplier));
		return b1.multiply(b2).doubleValue();
	}

	public static double multiply(double multiplicand, double... multipliers) {
		if (multipliers.length <= 0)
			return multiplicand;
		BigDecimal b1 = new BigDecimal(Double.toString(multiplicand));
		for (double multiplier : multipliers) {
			BigDecimal b2 = new BigDecimal(Double.toString(multiplier));
			b1 = b1.multiply(b2);
		}
		return b1.doubleValue();
	}
	
	/**
	 * 两个double数值相除
	 * 
	 * @param dividend
	 *            被除数
	 * @param divisor
	 *            除数
	 * @return
	 */
	public static double divide(double dividend, double divisor) {
		return divide(dividend, divisor, DEF_DIVIDE_SCALE);
	}

	/**
	 * 两个double数值相除（结果值四舍五入）
	 * @param dividend 被除数
	 * @param divisor 除数
	 * @param scale 保留小数位数
	 * @return
	 */
	public static double divide(double dividend, double divisor, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b1 = new BigDecimal(Double.toString(dividend));
		BigDecimal b2 = new BigDecimal(Double.toString(divisor));
		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 将double数值四舍五入保留指定位数小数
	 * @param value 需要四舍五入的值
	 * @param scale 小数位数
	 * @return
	 */
	public static double roundHalfUp(double value, int scale) {
		if (scale < 0)
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		return new BigDecimal(value).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 将BigDecimal数值四舍五入保留指定位数小数
	 * @param value 需要四舍五入的值
	 * @param scale 小数位数
	 * @return
	 */
	public static BigDecimal roundHalfUp(BigDecimal value, int scale) {
		if (scale < 0)
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		return value.setScale(scale, BigDecimal.ROUND_HALF_UP);
	}

	/**
	 * 将BigDecimal数值四舍五入保留指定位数小数
	 * @param value 需要四舍五入的值
	 * @param scale 小数位数
	 * @return
	 */
	public static BigDecimal roundDown(BigDecimal value, int scale) {
		if (scale < 0)
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		return value.setScale(scale, BigDecimal.ROUND_DOWN);
	}

}
